iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Mobile Development

關於 Flutter 開發的一些設計雜談系列 第 8

Day 8 - 當狀態遇上複雜的操作邏輯

  • 分享至 

  • xImage
  •  

當我們在開發 Flutter 時,有些時候我們會需要不斷的改變狀態,並把改變後的狀態渲染至畫面上。當隨著需求越來越複雜,改變狀態的邏輯也會開始變得複雜。假設今天有一個選擇相片的功能:畫面中有一個相片列表,使用者可以透過點擊相片選取,並且選取有些限制。
it_img_8_1.png
it_img_8_2.png
https://dartpad.dev/?id=dd689d7e21bfadcb7c2df8805552a3b6

一開始,我們會嘗試使用 StatefulWidget 來實現,但是從上面的程式碼可以得知,使用 StatefulWidget 會造成一個問題:那就是邏輯與畫面樣式混再一起,造成 Widget 違反了單一職責。

抽取類別

為了解決這個問題,我們來嘗試使用傳統物件導向的方式來解決。運用抽取類別的技巧,將複雜的選取邏輯抽到 SelectedPhotos 中,讓 SelectedPhotos 自己決定照片是否能被選取。

it_img_7_2.png
https://dartpad.dev/?id=886bcbddaf299475a141d22e7d099a4e

當我們把 SelectPhotos 的狀態與邏輯抽取至獨立類別後,原本的 Widget 就變得簡單許多。將 SelectPhotos 獨立成一個類別,我們也更好對其邏輯進行單元測試。關於測試的議題,我們會在未來的文章進行討論,這邊就不延伸討論。

狀態管理

在開發客端應用程式時,我們時常會需要在程式中維護狀態。使用者通過 UI 介面操作狀態,程式根據使用者的操作來改變狀態,最後把最終狀態渲染在畫面上。我們可以使用 StatefulWidget 來進行狀態管理,就像上面的例子一樣,但是當邏輯變得複雜,就會造成 Widget 變大而難以修改。

除了使用傳統的物件導向技巧處理,我們還可以選擇引入狀態管理套件,幫助我們簡化設計,在這邊我們使用 Riverpod 來修改上面的例子。

it_img_7_3.png
https://dartpad.dev/?id=427c1a2f44a98474a89f35e10aa9f313

相比於抽取類別的作法,使用狀態管理的作法會與前者有兩處不同

  1. 由狀態管理維護狀態:顧名思義,狀態管理主要關心的就是狀態,使用狀態管理,我們就不需要維護自己的 selectedPhotos 陣列,而是交由狀態管理維護,我們只需關注如何操作。
  2. 由狀態管理更新畫面:大多數的狀態管理套件都有一個重要的功能,那就是偵測狀態變化,一旦變化,就觸發畫面更新,而不需要我們自己使用 setState。

雖然在程式碼的長度並不會差很多,但實際上,使用狀態管理套件能讓我們更專注在操作狀態即可,是否重新渲染畫面則交由狀態管理決定,減輕 Widget 的負擔。

結論

當程式邏輯開始變得複雜時,適時的引入狀態管理套件,能有效的簡化設計。雖然在上面的例子中,我自己是使用 riverpod 解決問題,但是 Flutter 還有許多非常優秀的的狀態管理套件,例如:Bloc、Redux …等,Flutter 官方也有給出一些選項:List of state management approaches,大家在開發時,也可以參考看看。


上一篇
Day 7 - 跨元件分享狀態,橫跨數代的共同秘密
下一篇
Day 9 - 跨頁面共享狀態
系列文
關於 Flutter 開發的一些設計雜談30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言